#include "item.h"
#include "loc/rva.h"
#include <algorithm>

using namespace std;

bool Item::is_bound() { return is_bound_ == 1; }

std::string Item::subtype_name() { return subtype_; }

uint32 Item::subtype_index() { return subtype_index_; }

std::string Item::type_name() { return type_; }

uint32 Item::type_index() { return type_index_; }

string Item::name() { return name_; }

uint32 Item::num() { return num_; }

uint32 Item::rarity() { return rarity_; }

uint32 Item::level() { return level_; }

uint32 Item::min_level() { return min_level_; }

uint32 Item::price() { return price_; }

uint32 Item::item_id() { return item_id_; }

uintptr Item::ptr() { return obj_.ptr(); }

ObjType Item::type() { return obj_.type(); }

uint32 Item::index() { return obj_.index(); }

uint64 Item::id1() { return obj_.id1(); }

uint64 Item::id2() { return obj_.id2(); }

Item::Item(uint64 base, uint64 ptr, shared_ptr<ItemCache> cache)
    : base_{base}, obj_{ptr}, cache_{cache} {
  item_id_ = r4(ptr + 0x140);
  num_ = r4(ptr + 0x1A8);
  is_bound_ = r1(ptr + 0x1B0);
  auto prop = get_item_prop();
  if (prop > 0) {
    name_ = (char *)r8(prop + 0x48);
  } else {
    name_ = "未知名称";
  }
  rarity_ = r1(prop + 0x1CF);
  level_ = r2(prop + 0x17E);
  min_level_ = r1(prop + 0x1D1);
  price_ = r4(prop + 0x120);
  auto info = cache->get_item_type_info(item_id_);
  type_index_ = info.type_index;
  subtype_index_ = info.subtype_index;
  type_ = info.type;
  subtype_ = info.subtype;
}

Item::~Item() {}

unordered_map<uint32, uint64> Item::item_prop_map_{};

uint64 Item::get_item_prop() {
  auto it = item_prop_map_.find(item_id_);
  if (it != item_prop_map_.end()) {
    return it->second;
  }
  auto base = base_ + RVA_ITEM_PROP_BASE;
  auto item_id_min = r4(base + 0x1D0);
  auto item_id_max = r4(base + 0x1CC);
  if (item_id_ < item_id_min || item_id_ > item_id_max) {
    return 0;
  }
  auto arr = r8(r8(base + 0x140) + 0x80);
  auto size = r8(r8(base + 0x140) + 0x88);
  for (size_t i = 0; i < size; i++) {
    if (r4(arr + i * 0x10) == item_id_) {
      auto item_prop = r8(arr + i * 0x10 + 8);
      item_prop_map_.insert({item_id_, item_prop});
      return item_prop;
    }
  }
  return 0;
}
